package com.shihb.chapter03oop

import com.sun.corba.se.impl.orbutil.ObjectStreamClass_1_3_1

/**
 * Description: 类型约束
 * 泛型
 * 上下界介绍
 * 视界
 * 上下文界定Context bounds
 *
 * @author shihb
 * @date 2020/10/4 15:31
 */
object Demo13Generic {
  /**
   * 上界，比较int,double等实现Comparable接口的大小比较，返回最大值
   */
  def test1: Unit = {
    //implicit def int2Integer(x: Int)          = java.lang.Integer.valueOf(x)
    val value = new Compare[Integer](3, 2)
    println(value.greater)
    //  implicit def double2Double(x: Double)     = java.lang.Double.valueOf(x)
    val value2 = new Compare[java.lang.Double](3.2, 6.6)
    println(value2.greater)

  }

  /**
   * 视图界限，比较int,double等实现Comparable接口的大小比较，返回最大值
   */
  def test2: Unit = {
    // 这种写法是上界会报错,因为scala的没有实现Comparable接口
    //    println(new Compare(2,3)) //报错
    // 视界就不会报错
    // 隐式转换 @inline implicit def intWrapper(x: Int) = new runtime.RichInt(x)
    //final class RichInt(val self: Int) extends AnyVal with *ScalaNumberProxy[Int]* with RangedProxy[Int] {
    //trait *ScalaNumberProxy[T]* extends Any with ScalaNumericAnyConversions with Typed[T] with *OrderedProxy[T]*
    //trait *OrderedProxy[T]* extends Any with *Ordered[T]* with Typed[T] {
    //trait *Ordered[A]* extends Any with java.lang.Comparable[A] {
    println(new ViewCompare(2, 4).greater)
  }

  /**
   * 自定义隐式转换配合视界的案例
   */
  def test3: Unit ={
    val shb: Person = Person("shb", 30)
    val wyh: Person = Person("wyh", 29)
    // 引入隐式函数就能运行了
    import MyImplicit._
    println(new ViewCompare(shb, wyh).greater)
  }

  /**
   * 上下文界定
   */
  def test4: Unit ={
    val shb: Person = Person("shb", 30)
    val wyh: Person = Person("wyh", 29)
    //定义了 隐式值 会传到隐式参数
    implicit  val personComparetor = new Ordering[Person]{
      override def compare(x: Person, y: Person): Int = x.age-y.age
    }
    val value1 = new ContextCompare1(shb, wyh)
    val value2 = new ContextCompare2(shb, wyh)
    val value3 = new ContextCompare3(shb, wyh)
    println(value1.greater)
    println(value2.greater)
    println(value3.greater)
  }

  def main(args: Array[String]): Unit = {
    test4
  }



}
object MyImplicit{
  // 这两种写法都可以
//  implicit class PersonOrder(person: Person) extends Ordered[Person]{
//    override def compare(that: Person): Int = person.age-that.age
//  }
  implicit def persion2OrderPerson(person: Person):Ordered[Person]=new Ordered[Person]{
    override def compare(that: Person): Int = person.age-that.age
  }

}


case class Person(name:String,age:Int)
// T<:Comparable[T] 表示传入的类型T是Comparable接口的子类型，继承了Comparable
class Compare[T <: Comparable[T]](o1: T, o2: T) {
  //o1.compareTo(o2)>0 o1大
  def greater = if (o1.compareTo(o2) > 0) o1 else o2
}
// view bounds
class ViewCompare[T <% Comparable[T]](o1: T, o2: T) {
  //o1.compareTo(o2)>0 o1大
  def greater = if (o1.compareTo(o2) > 0) o1 else o2
}
// context bounds 方式一
// implicit compartor: Ordering[T]就是隐式参数
class ContextCompare1[T:Ordering](o1: T, o2: T)(implicit compartor: Ordering[T]) {
  //o1.compareTo(o2)>0 o1大
  def greater = if (compartor.compare(o1,o2)>0) o1 else o2
}
// context bounds 方式二
// implicit compartor: Ordering[T]就是隐式参数内置到方法里
class ContextCompare2[T:Ordering](o1: T, o2: T) {
  //o1.compareTo(o2)>0 o1大
  def f1(implicit compartor: Ordering[T])=compartor.compare(o1,o2)
  def greater = if (f1>0) o1 else o2
}

// context bounds 方式三:推荐使用
// implicit compartor: Ordering[T]就是隐式参数内置到方法里
class ContextCompare3[T:Ordering](o1: T, o2: T) {
  //o1.compareTo(o2)>0 o1大
  //@inline def implicitly[T](implicit e: T) = e
  val compartor = implicitly [Ordering[T]]
  def greater = if (compartor.compare(o1,o2)>0) o1 else o2
}

